package online.inote.mapper.base;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import tk.mybatis.mapper.entity.Example;

public class BaseService<T extends IdEntity> extends GenericService<T> {

	@Autowired
	protected BaseMapper<T> mapper;
	
	public List<T> select(T record) {
		return mapper.select(record);
	}
	
	public List<T> selectAll() {
		return mapper.selectAll();
	}
	
	public List<T> selectByExample(Example example) {
		return mapper.selectByExample(example);
	}
	
	public List<T> selectListByPropertyEqualTo(String property, Object value) {
		Example example = new Example(clazz);
		example.createCriteria().andEqualTo(property, value);
		
		return mapper.selectByExample(example);
	}
	
	public T selectByPropertyEqualTo(String property, Object value, MultipleResultsHandle handle) {
		
		if (!MultipleResultsHandle.contains(handle))
			throw new RuntimeException("未知的处理方式");
		
		List<T> list = this.selectListByPropertyEqualTo(property, value);
		
		if (CollectionUtils.isEmpty(list)) {
			return null;
		} else if (list.size() > 1) {
			if (MultipleResultsHandle.IGNORE.equals(handle)) {
				return list.get(0);
			} else if (MultipleResultsHandle.EXCEPTION.equals(handle)) {
				throw new RuntimeException("查询单条数据时, 返回多条数据！class:[ " + clazz + " ]");
			}
		}
		
		return list.get(0);
	}
	
	public List<T> selectByExampleAndRowBounds(Example example, RowBounds rowBounds) {
		return mapper.selectByExampleAndRowBounds(example, rowBounds);
	}
	
	public T selectByPrimaryKey(Object key) {
		return mapper.selectByPrimaryKey(key);
	}
	
	public List<T> selectByRowBounds(T record, RowBounds rowBounds) {
		return mapper.selectByRowBounds(record, rowBounds);
	}
	
	public int selectCount(T record) {
		return mapper.selectCount(record);
	}
	
	public int selectCountByExample(Example example) {
		return mapper.selectCountByExample(example);
	}
	
	public T selectOne(T record) {
		return mapper.selectOne(record);
	}
	
	public T selectOneByExample(Example example) {
		return mapper.selectOneByExample(example);
	}
	
	public String insert(T record) {
		
		if (StringUtils.isEmpty(record.getId())) {
			record.generatedId();
		}
		
		this.mapper.insert(record);
		
		return record.getId();
	}
	
	public String insertSelective(T record) {
		
		if (StringUtils.isEmpty(record.getId())) {
			record.generatedId();
		}
		
		this.mapper.insertSelective(record);
		
		return record.getId();
	}
	
	public int updateByExample(T record, Example example) {
		return mapper.updateByExample(record, example);
	}
	
	public int updateByExampleSelective(T record, Example example) {
		return mapper.updateByExampleSelective(record, example);
	}
	
	public int updateByPrimaryKey(T record) {
		return mapper.updateByPrimaryKey(record);
	}
	
	public int updateByPrimaryKeySelective(T record) {
		return mapper.updateByPrimaryKeySelective(record);
	}
	
	public int delete(T record) {
		return mapper.delete(record);
	}
	
	public int delete(Example example) {
		return mapper.deleteByExample(example);
	}
	
	public int deleteByPrimaryKey(Object key) {
		return mapper.deleteByPrimaryKey(key);
	}
	
	public boolean existsWithPrimaryKey(Object key) {
		return mapper.existsWithPrimaryKey(key);
	}
	
	public enum MultipleResultsHandle {
		IGNORE,			// 忽略, 返回第一条
		EXCEPTION;		// 抛出异常, 进行警告
		
		public static Set<MultipleResultsHandle> MultipleResultsHandleSet;
		
		static {
			MultipleResultsHandleSet = new HashSet<>(Arrays.asList(values()));
		}
		
		public static boolean contains(MultipleResultsHandle handle) {
			return MultipleResultsHandleSet.contains(handle);
		}
	}
}